{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "29e5c911-fa2d-4593-8565-3b7bb127b53d",
   "metadata": {},
   "source": [
    "# LangChain 核心模块 Agent - Self ask with search\n",
    "\n",
    "- Google 搜索对接\n",
    "    - 第三方平台：https://serpapi.com\n",
    "    - LangChain API 封装：`SerpAPIWrapper`\n",
    "- LangChain Agent 模块使用\n",
    "    - Agent 类型：`SELF_ASK_WITH_SEARCH`\n",
    "    - Agent 实例化：`initialize_agent` 方法\n",
    " \n",
    "https://python.langchain.com/docs/modules/agents/agent_types/"
   ]
  },
  {
   "cell_type": "code",
   "id": "2866704f-c203-4c97-8221-c2ecadc52b4c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:40:48.966283Z",
     "start_time": "2024-07-13T06:40:48.945812Z"
    }
   },
   "source": [
    "import os\n",
    "\n",
    "# 更换为自己的 Serp API KEY\n",
    "# os.environ[\"SERPAPI_API_KEY\"] = \"1e3c93e0753ac224098370cd71da86150c6609caba6b5aaa307e04b72a5006e1\"\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"f805ac0b9ece2ec2c2ba22584afed0d6fc881a86cf541c39962ecdb9ea330d25\""
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "cell_type": "code",
   "id": "add0b59e-9e30-41a1-9a4e-bacf8aefb3e9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:52:17.622855Z",
     "start_time": "2024-07-13T06:52:16.769803Z"
    }
   },
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "from langchain.utilities import SerpAPIWrapper\n",
    "from langchain.agents import initialize_agent, AgentType, Tool\n",
    "\n",
    "llm = ChatOpenAI(temperature=0, model=\"gpt-4\")"
   ],
   "outputs": [],
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "id": "7047f1b0-a29c-497e-badc-d02fbcbf4082",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:40:56.029221Z",
     "start_time": "2024-07-13T06:40:56.009772Z"
    }
   },
   "source": [
    "# 实例化查询工具\n",
    "search = SerpAPIWrapper()\n",
    "tools = [\n",
    "    Tool(\n",
    "        name=\"Intermediate Answer\",\n",
    "        func=search.run,\n",
    "        description=\"useful for when you need to ask with search\",\n",
    "    )\n",
    "]"
   ],
   "outputs": [],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "id": "08a5daa3-fc7a-4ce9-aa46-ad4a6d31be74",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:41:37.088184Z",
     "start_time": "2024-07-13T06:41:37.069019Z"
    }
   },
   "source": [
    "# 实例化 SELF_ASK_WITH_SEARCH Agent\n",
    "self_ask_with_search = initialize_agent(\n",
    "     tools,llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True\n",
    ")"
   ],
   "outputs": [],
   "execution_count": 7
  },
  {
   "cell_type": "code",
   "id": "508c39d7-05d9-4486-83bc-924cd6a1c499",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:52:25.331512Z",
     "start_time": "2024-07-13T06:52:20.575258Z"
    }
   },
   "source": [
    "# 实际运行 Agent，查询问题（正确）\n",
    "self_ask_with_search.invoke(\n",
    "    \"成都举办的大运会是第几届大运会？\"\n",
    ")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3mYes.\n",
      "\n",
      "Follow up: 成都举办的大运会是哪一年举办的？\u001B[0m\n",
      "Intermediate answer: \u001B[36;1m\u001B[1;3m大运会所有必选竞赛项目全部是奥运项目，竞赛管理由国际单项体育组织按照奥运标准实施，是规模仅次于奥运会的世界综合性运动会，素有“小奥运会”之称。 2023年7月28日至8月8日，第31届世界大学生夏季运动会在四川成都举办。\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3mIntermediate answer: 2023年7月28日至8月8日，第31届世界大学生夏季运动会在四川成都举办。\n",
      "So the final answer is: 第31届\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': '成都举办的大运会是第几届大运会？', 'output': '第31届'}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 16
  },
  {
   "cell_type": "code",
   "id": "5fe1f2de-f982-4953-9e8e-7f99a8289975",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:53:15.927207Z",
     "start_time": "2024-07-13T06:53:14.730138Z"
    }
   },
   "source": [
    "# 实际运行 Agent，查询问题（有歧义）\n",
    "self_ask_with_search.run(\n",
    "    \"2023年大运会举办地在哪里？\"\n",
    ")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3mNo.\n",
      "\n",
      "So the final answer is: 成都, 中国 (Chengdu, China)\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'成都, 中国 (Chengdu, China)'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 17
  },
  {
   "cell_type": "code",
   "id": "e1cf918e-a58a-4790-a4c4-2109f23dd064",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:53:23.462732Z",
     "start_time": "2024-07-13T06:53:21.236682Z"
    }
   },
   "source": [
    "# Reason-only 答案（错误）\n",
    "print(llm.invoke(\"成都举办的大运会是第几届大运会？\"))"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='成都举办的是第31届大运会。' response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 27, 'total_tokens': 43}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-3f9c4420-f5f0-401c-87f9-2faf1ccad0d4-0'\n"
     ]
    }
   ],
   "execution_count": 18
  },
  {
   "cell_type": "code",
   "id": "32021fdf-2597-4dde-a425-13650904671f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:53:30.105930Z",
     "start_time": "2024-07-13T06:53:28.233197Z"
    }
   },
   "source": [
    "# Reason-only 答案（错误）\n",
    "print(llm.invoke(\"2023年大运会举办地在哪里？\"))"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='2023年大运会的举办地在中国的成都市。' response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 23, 'total_tokens': 42}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-f130e954-8511-467c-afb7-4467b30d2cd6-0'\n"
     ]
    }
   ],
   "execution_count": 19
  },
  {
   "cell_type": "markdown",
   "id": "b73c7bd9-a835-41c1-bf28-4e203c22538b",
   "metadata": {},
   "source": [
    "#### 使用 GPT-4 作为大语言模型实现更优的 ReAct 范式"
   ]
  },
  {
   "cell_type": "code",
   "id": "d98ba940-a6e8-477e-83a9-2e20115ff51d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:37:54.340726Z",
     "start_time": "2024-07-13T06:37:53.464937Z"
    }
   },
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "chat_model = ChatOpenAI(model=\"gpt-4-1106-preview\", temperature=0)"
   ],
   "outputs": [],
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "id": "fc4347f2-4a16-4406-92c7-d2156478bb56",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:37:56.170321Z",
     "start_time": "2024-07-13T06:37:56.156179Z"
    }
   },
   "source": [
    "self_ask_with_search_chat = initialize_agent(\n",
    "    tools, chat_model, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True\n",
    ")"
   ],
   "outputs": [],
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "id": "25978771-8e69-41f2-b9e8-b287d846e1cd",
   "metadata": {},
   "source": [
    "# GPT-4 based ReAct 答案（正确）\n",
    "self_ask_with_search_chat.run(\n",
    "    \"2023年大运会举办地在哪里？\"\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "94da622a-8bdd-4cf3-bc7a-bcfbf88c54f4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-13T06:38:34.778777Z",
     "start_time": "2024-07-13T06:38:28.012078Z"
    }
   },
   "source": [
    "# 实际运行 Agent，查询问题（正确）\n",
    "self_ask_with_search_chat.invoke(\n",
    "    \"成都举办的大运会是第几届大运会？\"\n",
    ")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3mYes.\n",
      "Follow up: 成都举办的大运会是哪一年的？\u001B[0m\n",
      "Intermediate answer: \u001B[36;1m\u001B[1;3m2021年夏季世界大学生运动会（英语：2021 Summer World University Games）简称为2021年成都大运会或成都大运会，是第31届夏季世界大学生运动会，原定于2021年于中国四川省成都市举行，后因2019冠状病毒病疫情等原因二次延期，最终改至2023年7月28日至8月8日举行。\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3mSo the final answer is: 第31届大运会\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': '成都举办的大运会是第几届大运会？', 'output': '第31届大运会'}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 13
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
